home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / grafik / cbgi111 / src / dt2851 / dt2851.c next >
Encoding:
C/C++ Source or Header  |  1990-07-11  |  36.0 KB  |  1,066 lines

  1. /*************************** DT2851 DRIVER ******************************/
  2. /*    Data Translation DT2851 BGI driver.  This program acts as a BGI */
  3. /*  driver for the Data Translation DT2851.  In this card the memory is */
  4. /*  mapped as follows.  One pixel per byte, laid out linearly in     */
  5. /*  EXTENDED!!! memory.  Since the video memory is in extended memory    */
  6. /*  room is reserved in the driver to buffer a single line for drawing.    */
  7. /*  In a special graphics drawing mode this will be updated to video    */
  8. /*  memory only when moving to a new row.  Otherwise it is updated    */
  9. /*  after each drawing operation.  This driver uses some AT bios     */
  10. /*  functions to access extended memory.                */
  11. /*                                    */
  12. /*    V 1.00  18/05/90  Robert Adsett Clean up the comments some.     */
  13. /*                This is the release version.  Some    */
  14. /*                features are not fully implemented yet    */
  15. /*                but it seems solid enough.        */
  16. /*    V 1.01    11/07/90  Robert Adsett Was copying one too many rows    */
  17. /*                    in save/restore bitmap.        */
  18. /*                                    */
  19. /*  LIMITATIONS:                            */
  20. /*    Flood fill is unimplemented at present.                */
  21. /*    Error checking & reporting are almost non-existant.        */
  22. /*    Everything that can be emulated is.  This seems to be         */
  23. /*   reasonably fast so changing this is not a high priority.        */
  24. /*                                    */
  25. /*  KNOWN BUGS:                                */
  26. /*    Line width is currently ignored.  This seems to be taken care    */
  27. /*   of by the kernal but should be changed.                */
  28. /************************************************************************/
  29.  
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "bgi.h"
  33. #include "dt2851.h"
  34.  
  35. /*    Generic driver global variables.  Should be present in almost    */
  36. /*  every driver.                            */
  37.  
  38. const CHAR_TABLE_ENTRY far * const char_def = 
  39.             (CHAR_TABLE_ENTRY far *)MK_FP( 0xf000, 0xfa6e);
  40.                 /* Pointer to character definition    */
  41.                 /*  table in ROM.            */
  42.  
  43.                 /* Fill pattern definitions.        */
  44. const FILLPATTERN def_patterns[12] = {
  45.         { 0, 0, 0, 0, 0, 0, 0, 0 },     /* No Fill.        */
  46.         { 0xff, 0xff, 0xff, 0xff, 
  47.           0xff, 0xff, 0xff, 0xff },    /* Solid Fill.        */
  48.         { 0xff, 0xff, 0, 0, 0xff, 
  49.           0xff, 0, 0},            /* Line Fill.        */
  50.         { 1, 2, 4, 8, 0x10, 0x20,
  51.           0x40, 0x80},            /* Lt Slash fill.    */
  52.         { 0xE0, 0xC1, 0x83, 0x07, 
  53.           0x0E, 0x1C, 0x38, 0x70 },    /* Slash Fill.        */
  54.         { 0xF0, 0x78, 0x3C, 0x1E, 
  55.           0x0F, 0x87, 0xC3, 0xE1 },    /* Backslash Fill.    */
  56.         { 0xA5, 0xD2, 0x69, 0xB4, 
  57.           0x5A, 0x2D, 0x96, 0x4B },    /* Lt Backslash Fill.    */
  58.         { 0xFF, 0x88, 0x88, 0x88, 
  59.           0xFF, 0x88, 0x88, 0x88 },    /* Hatch Fill.        */
  60.         { 0x81, 0x42, 0x24, 0x18, 
  61.           0x18, 0x24, 0x42, 0x81 },    /* XHatch Fill.        */
  62.         { 0xCC, 0x33, 0xCC, 0x33, 
  63.           0xCC, 0x33, 0xCC, 0x33 },    /* Interleave Fill.    */
  64.         { 0x80, 0x00, 0x08, 0x00, 
  65.           0x80, 0x00, 0x08, 0x00 },     /* Wide Dot Fill.    */
  66.         { 0x88, 0x00, 0x22, 0x00, 
  67.           0x88, 0x00, 0x22, 0x00 }    /* Close Dot Fill.    */
  68.            };
  69. /*                                    */
  70. /*    The following structure defines the Bit Manipulation Utility    */
  71. /*    function table.                            */
  72. /*                                    */
  73.  
  74. const UTILITIES Utility_Table = {    /* Bit Utilities Function Table */
  75.   (NRFPTR) dispatch_enter_graphics,    /* Enter graphics mode function */
  76.   (NRFPTR) dispatch_leave_graphics,    /* Leave graphics mode function */
  77.   (NRFPTR) dispatch_putpix,        /* Write a pixel function    */
  78.   (NRFPTR) dispatch_getpix,        /* Read a pixel function    */
  79.   (NRFPTR) dispatch_bits_per_pixel,    /* Bits per pixel value        */
  80.   (NRFPTR) dispatch_set_page,        /* Set the active drawing page    */
  81.   (NRFPTR) dispatch_set_visual,        /* Set the active display page    */
  82.   (NRFPTR) dispatch_set_write_mode    /* Set the current write mode    */
  83.   };
  84.  
  85. int MAXY = 479, MAXX = 511, MINY = 0,     /* Clipping limits.        */
  86.     MINX = 0;
  87. unsigned int current_line_style = 0xffff;    /* Current line drawing    */
  88.                         /*  style.        */
  89. int current_write_mode = COPY;        /* Current drawing mode.    */
  90. int current_line_width = 1;        /* Current line width.        */
  91. unsigned char current_colour = 0xff,     /* Current drawing,        */
  92.           fill_colour = 0xff,    /*  filling,            */
  93.               background_colour = 0;    /*  and background colour.    */
  94.  
  95. unsigned int    CP_X = 0, CP_Y = 0;    /* Current Drawing Pointer CP.    */
  96. unsigned int    char_size, char_path;    /* Current character size and    */
  97.                     /*  drawing path.        */
  98.  
  99. const unsigned int line_style_mask[16] = {    /* A set of bit masks    */
  100.                     0x8000,    /*  used to mask bits    */
  101.                     0x4000,    /*  from the current    */
  102.                     0x2000,    /*  line style.        */
  103.                     0x1000,
  104.                     0x0800,
  105.                     0x0400,
  106.                     0x0200,
  107.                     0x0100,
  108.                     0x0080,
  109.                     0x0040,
  110.                     0x0020,
  111.                     0x0010,
  112.                     0x0008,
  113.                     0x0004,
  114.                     0x0002,
  115.                     0x0001
  116.                     };
  117.  
  118. STATUS    Stat_Block = {        /* Device status block.            */
  119.   0,                /* Current device status.        */
  120.   0,                /* Device Type Identifier.        */
  121.   511,                /* Device Full Resolution in X        */
  122.   479,                /* Device Full Resolution in Y        */
  123.   511,                /* Device Effective X Resolution    */
  124.   479,                /* Device Effective Y Resolution    */
  125.   9000,                /* Device X Size in inches*1000        */
  126.   7000,                /* Device Y Size in inches*1000        */
  127.   10000,            /* Aspect Ratio * 10000            */
  128.                   /* For compatibility the other fields     */
  129.                 /*  set so.                */
  130.   8,
  131.   8,
  132.   0x90,
  133.   0x90
  134.   };
  135.  
  136. NN9PALETTE Default_Palette = {    /* Default palette.              */
  137.   16, { 0x00, 0x00, 0x00,    /* In this case set during startup.    */
  138.       0x00, 0x00, 0x0f,    0x00, 0x0f, 0x00,    0x00, 0x00, 0x03,
  139.     0x00, 0x00, 0x04,    0x00, 0x00, 0x05,    0x00, 0x00, 0x07,
  140.     0x00, 0x00, 0x14,    0x00, 0x00, 0x38,    0x00, 0x00, 0x39,
  141.     0x00, 0x00, 0x3A,    0x00, 0x00, 0x3B,    0x00, 0x00, 0x3C,
  142.     0x00, 0x00, 0x3D,    0x00, 0x00, 0x3E,    0x00, 0x00, 0x3F,
  143.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  144.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  145.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  146.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  147.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  148.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  149.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  150.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  151.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  152.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  153.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  154.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  155.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  156.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  157.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  158.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  159.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  160.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  161.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  162.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  163.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  164.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  165.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  166.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  167.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  168.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  169.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  170.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  171.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  172.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  173.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  174.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  175.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  176.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  177.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  178.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  179.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  180.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  181.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  182.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  183.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  184.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  185.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  186.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  187.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  188.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  189.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  190.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  191.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  192.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  193.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  194.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  195.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  196.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  197.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  198.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  199.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  200.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  201.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  202.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  203.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  204.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  205.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  206.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  207.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  208.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  209.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  210.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  211.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  212.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  213.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  214.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  215.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  216.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  217.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  218.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  219.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  220.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  221.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  222.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0xff, 0xff, 0xff}
  223.   };
  224.  
  225. /* Global variables specific to this driver.                */
  226.  
  227. int  base = 0x230;            /* Ports for controlling the    */
  228.                     /*   DT2851 start here.        */
  229. unsigned char line_buffer[ 512];    /* Buffer each line here as we    */
  230.                     /*  work on it.            */
  231. int  graphics_mode = 0;            /* Special pixel writing mode.    */
  232. unsigned long page_offset = 0;        /* Start of current graphics    */
  233.                     /*  page.            */
  234. unsigned int current_row = 0;        /* Current row.            */
  235. unsigned int current_column = 0;    /* Current column.        */
  236. unsigned char current_pattern[8][8];    /* Current fill pattern stored    */
  237.                     /*  as pixels.            */
  238.  
  239. /*                                    */
  240. /*    Function Protoypes local to the ATI driver.            */
  241. /*                                    */
  242.  
  243. void copy_image( 
  244.     unsigned char const far *from, 
  245.     int from_xsize, 
  246.         unsigned char far *to, 
  247.     int to_xsize,
  248.     int mode
  249.     );
  250. void char_draw( unsigned char c);
  251. void set_pattern( unsigned char *current_pattern, 
  252.           unsigned char const far *pattern);
  253. void update_pattern( void);
  254.  
  255.  
  256. /******************************* INSTALL ********************************/
  257. /*    The Install function is used to prepare the driver to use.  The    */
  258. /*  calls to this function allow the kernal to inquire the mode     */
  259. /*  information, and allow the kernal to install the mode infomation.    */
  260. /*  sets the error code to 'grInvalidMode' for invalid mode numbers    */
  261. /*  and 'grError' for an unrecognized command.                */
  262. /************************************************************************/
  263.  
  264. const char *CopyRight = 
  265.   "Data Translation DT2851 BGI driver (V 1.00) Copyright R. Adsett 1990.";
  266.  
  267.                 /* Names of the drivers modes.  The     */
  268.                 /*  first character is the length of     */
  269.                 /*  the string.                */
  270. char *Name[] = {
  271.         "\x2a Data Translation DT2851 (512 x 480 x 256)"
  272.         };
  273.  
  274. long install(
  275.     unsigned int mode,    /* Mode to use.                */
  276.     char command        /* Install sub command.            */
  277.     )
  278. {
  279. long ret_code;
  280.  
  281. switch( command )            /* Determine the command to use */
  282.     {
  283.     case 0:                /* Install Device Command.    */
  284.          if((mode & 0xff) >= MAX_MODES)    /* Is the mode requested valid? */
  285.               {                /*  No set an error code.    */
  286.               Stat_Block.stat = grInvalidMode;
  287.           }
  288.          ret_code = (unsigned int)&Stat_Block;    /* Return pointer to     */
  289.          break;                    /*  the status block.    */
  290.  
  291.     case 1:                /* Mode Query Command.        */
  292.          ret_code = (long)MAX_MODES << 16; /* Return number of modes.    */
  293.          break;
  294.  
  295.     case 2:                /* Mode Name Command.        */
  296.          if( (mode & 0xff) > MAX_MODES)    /* Is the mode requested valid? */
  297.               {                /*  No set an error code.    */
  298.               Stat_Block.stat = grInvalidMode;
  299.           }
  300.                           /* Return pointer to the name.    */
  301.          ret_code = (unsigned int)Name[mode & 0xff];
  302.          break;
  303.  
  304.     default:                /* Unknown Install Call.    */
  305.          Stat_Block.stat = grError;    /* General error.        */
  306.          break;
  307.     }                    /* End of Install command case.    */
  308. return( ret_code);            /* Return pointer, mode numbers */
  309. }
  310.  
  311. /******************************* INITIALIZE *****************************/
  312. /*    The initialize function is used to enter the graphics mode.    */
  313. /*  Save the current mode so that it can be restored later.        */
  314. /************************************************************************/
  315.  
  316. void init( unsigned int dit_offset, unsigned int dit_segment)
  317. {
  318. struct DIT far *Dev_info;
  319. int i;
  320. unsigned int prev_incsr1, prev_incsr2;
  321.  
  322. Dev_info = (struct DIT far *)MK_FP( dit_segment, dit_offset);
  323.  
  324. background_colour = Dev_info->background;
  325.                     /* Set the background colour.    */
  326. update_pattern();            /* Set up the pattern for use.    */
  327.  
  328. if( Dev_info->init != 0xA5)        /* Don't ask me!        */
  329.     {
  330.     DISPLAY( OFF);            /* Turn off the display.    */
  331.     EXT_TIME( OFF);            /* Use internal crystal for    */
  332.                         /*  video timing.        */
  333.     ENSTOP( ON);            /* Set to single operation mode.*/
  334.     BUSY( OFF);                /* Stop current operation.    */
  335.     INTERRUPT_ON_DONE( OFF);        /* Turn off interrupt (let's be    */
  336.                         /*  safe).            */
  337.     MODE( FEEDBACK);
  338.     prev_incsr2 = inport( INCSR2);
  339.     MODE( LOAD_LUT);            /* Set to load lookup table's    */
  340.                         /*  mode.            */
  341.     INPUT_LUT( 0);            /* Select input and output     */
  342.     OUTPUT_LUT( 0);            /*  lookup tables.        */
  343.     for( i = 0; i < MAX_COLOURS; i++)    /* Set input lut to map each    */
  344.          {                /*  input to itself.        */
  345.          INPUT_LUT_ENTRY( i, i);
  346.      }
  347.     outport( INCSR2, prev_incsr2);
  348.     palette( 0x80ff, 0xff,  0xff, 0xff);/* Last Palette entry is bright    */
  349.                     /*  white.  Set the rest to the    */
  350.                     /*  EGA defaults.        */
  351.  
  352.     palette( 0x8000, 0x00,  0x00, 0x00);    /* Black.        */
  353.     palette( 0x8001, 0x00,  0x00, 0x7f);    /* Blue.        */
  354.     palette( 0x8002, 0x00,  0x7f, 0x00);    /* Green.        */
  355.     palette( 0x8003, 0x00,  0x7f, 0x7f);    /* Cyan.        */
  356.     palette( 0x8004, 0x7f,  0x00, 0x00);    /* Red.            */
  357.     palette( 0x8005, 0x7f,  0x00, 0x7f);    /* Magenta.        */
  358.     palette( 0x8006, 0x7f,  0x7f, 0x00);    /* Broen.        */
  359.     palette( 0x8007, 0x9f,  0x9f, 0x9f);    /* LightGray.        */
  360.     palette( 0x8008, 0x5f,  0x5f, 0x5f);    /* DarkGray.        */
  361.     palette( 0x8009, 0x00,  0x00, 0xff);    /* LighBlue.        */
  362.     palette( 0x800a, 0x00,  0xff, 0x00);    /* LightGreen.        */
  363.     palette( 0x800b, 0x00,  0xff, 0xff);    /* LightCyan.        */
  364.     palette( 0x800c, 0xff,  0x00, 0x00);    /* LightRed.        */
  365.     palette( 0x800d, 0xff,  0x00, 0xff);    /* LightMagenta.    */
  366.     palette( 0x800e, 0xff,  0xff, 0x00);    /* Yellow.        */
  367.     palette( 0x800f, 0xff,  0xff, 0xff);    /* White.        */
  368.    
  369.     /*  Get a copy of the default palette.                */
  370.     prev_incsr2 = inport( INCSR2);
  371.     MODE( LOAD_LUT);            /* Set to load lookup table's    */
  372.                         /*  mode.            */
  373.     for( i = 0; i < MAX_COLOURS; i++)
  374.          {
  375.          Default_Palette.colora[(i*3)] = INPUT_LUT_RED_ENTRY( i);
  376.          Default_Palette.colora[(i*3) + 1] = INPUT_LUT_GREEN_ENTRY( i);
  377.          Default_Palette.colora[(i*3) + 2] = INPUT_LUT_BLUE_ENTRY( i);
  378.          }
  379.     outport( INCSR2, prev_incsr2);
  380.     MODE( FEEDBACK);
  381.     INPUT_PAGE( 0);            /* Input (digitized) goes to    */
  382.                         /*  page 0.            */
  383.     WRITE_PROTECT( 0);            /* No write protect on bit     */
  384.                         /*  planes.            */
  385.     DISPLAY_PAGE( 0);            /* Display page 0.        */
  386.     DISPLAY( ON);            /* Turn the display on.        */
  387.     }
  388. }
  389.  
  390. /******************************* CLEAR **********************************/
  391. /*    Clear the screen.  Write zero everywhere.              */
  392. /************************************************************************/
  393.  
  394. void clear( void )
  395. {
  396.  
  397.     /* Clear local line once and copy it to the display adapter for    */
  398.     /*  each row on the screen.                    */
  399. memset( line_buffer, 0, 512);
  400. for( current_row = 0; current_row < 512; current_row++)
  401.     {
  402.     ROW_UPDATE();
  403.     }
  404. }
  405.  
  406. /********************************** POST ********************************/
  407. /*    Go to text mode.  Null function, there is no text mode.        */
  408. /************************************************************************/
  409.  
  410. void post( void )
  411. {
  412. }
  413.  
  414. /********************************* MOVE *********************************/
  415. /*    This function is used to move the current pointer (CP). This is    */
  416. /*  a pretty generic routine, library later?                  */
  417. /************************************************************************/
  418.  
  419. void move( int x, int y)
  420. {
  421.  
  422. CP_X = x;                /* Update the current pointer.    */
  423. CP_Y = y;
  424. }
  425.  
  426. /******************************** DRAW **********************************/
  427. /*    Draw a line vector from the CP to the specified coordinate.    */
  428. /*  Update the CP to the new coordinate.                */
  429. /************************************************************************/
  430.  
  431. void draw( int x, int y)
  432. {
  433.  
  434. line( CP_X, CP_Y, x, y);        /* Draw the line.        */
  435. CP_X = x;                /* Update the current pointer    */
  436. CP_Y = y;
  437. }
  438.  
  439. /********************************* VECT *********************************/
  440. /*    Draw a line between the two specified points.            */
  441. /************************************************************************/
  442.  
  443. void vect( int x1, int y1, int x2, int y2)
  444. {
  445.  
  446. line( x1, y1, x2, y2);        /* Draw the line.            */
  447. }
  448.  
  449. /********************************* PATBAR *******************************/
  450. /*    Fill a rectangle with the current filling pattern.  Do not     */
  451. /*  outline.  The coordinates passed are the upper left corner and the    */
  452. /*  lower right corner.                            */
  453. /************************************************************************/
  454.  
  455. void patbar( int x1, int y1, int x2, int y2)
  456. {
  457. int x3, y3;
  458.  
  459. if( x2 < x1)            /* Sometimes the emulation routines get    */
  460.     {                /*   the y coords. backwards.  We'll    */
  461.     x3 = x2; x2 = x1; x1 = x3;    /*   check the x coords. as well just     */
  462.     }                /*   to be sure.            */
  463. if( y2 < y1)
  464.     {
  465.     y3 = y2; y2 = y1; y1 = y3;
  466.     }
  467. for( ; y1 <= y2; y1++)        /* For each line.            */
  468.     {
  469.     int pre_done;
  470.  
  471.     x3 = x1;
  472.     y3 = y1;
  473.     pre_done = 0;
  474.     CALC_ADDR( x3, y3);        /* Calculate start address....        */
  475.     if( (x3 & 7) != 0)
  476.          {
  477.      int size;
  478.  
  479.      pre_done = 8 - x3 & 7;
  480.      size = ((x2-x1+1) < pre_done) ? (x2-x1+1) : pre_done;
  481.          copy_image( ¤t_pattern[y1&7][x3&7], pre_done, 
  482.                  &line_buffer[ current_column], size, COPY);
  483.          CALC_ADDR( x3 + pre_done, y3);    /* Calculate start address....    */
  484.      }
  485.     if( pre_done < x2-x1+1)
  486.          {
  487.      int size;
  488.  
  489.      size = x2 - x1 + 1 - pre_done;
  490.          copy_image( current_pattern[y1&7], 8, 
  491.                  &line_buffer[ current_column], size, COPY);
  492.                     /* ... and copy appropriate line of the    */
  493.                 /*  current pattern in.            */
  494.      }
  495.     ROW_UPDATE();
  496.     }
  497. }
  498.  
  499. /******************************* PALETTE ********************************/
  500. /*    Set the colour palette entries.  Only the set RGB colour method    */
  501. /*  is supported.                            */
  502. /************************************************************************/
  503.  
  504. void palette( int flag_index, int red_colour,  int blue, int green)
  505. {
  506. int index;
  507. unsigned char r, g, b;
  508. unsigned int prev_incsr2;
  509.  
  510. index = flag_index & 0x3fff;        /* Grab colour table index.    */
  511. r = red_colour & 0xff;            /* Grab colours.        */
  512. g = green & 0xff;
  513. b = blue & 0xff;
  514. switch(flag_index & 0xc000)
  515.     {
  516.     case 0x4000:
  517.          /*    unused.                            */
  518.      break;
  519.  
  520.     case 0x0000:            /* Load colour table with colour*/
  521.      b = r & 3;            /*  in red_colour.  It's mapped    */
  522.      g = (r >> 2) & 3;        /*  as 2 bits each for red,     */
  523.      r = (r >> 4) & 3;        /*  green, and blue.  Set up    */
  524.      /*FALLTHROUGH*/        /*  and let setrgb do the work.    */
  525.  
  526.     case 0x8000:            /* Load rgb.            */
  527.          prev_incsr2 = inport( INCSR2);
  528.          MODE( LOAD_LUT);
  529.          OUTPUT_LUT_RED_ENTRY( index, r);
  530.          OUTPUT_LUT_GREEN_ENTRY( index, g);
  531.          OUTPUT_LUT_BLUE_ENTRY( index, b);
  532.          outport( INCSR2, prev_incsr2);
  533.      break;
  534.          
  535.     case 0xc000:            /*  Load background.        */
  536.          background_colour = r;
  537.      break;
  538.     }
  539. }
  540.  
  541. /****************************** ALLPALETTE ******************************/
  542. /*    The BGI kernal only passes the first 16 entries.  Therefore     */
  543. /*  this function ignores the passed argument and simply restores the    */
  544. /*  default palette.  (At least that way the results are consistent).     */
  545. /************************************************************************/
  546.  
  547. void allpalette( unsigned int pptr_offset, unsigned int pptr_segment)
  548. {
  549. int i;
  550.  
  551. for( i = 0; i < MAX_COLOURS; i++)
  552.     {
  553.     palette( 0x8000 | i, Default_Palette.colora[(i*3)], 
  554.              Default_Palette.colora[(i*3)+1], 
  555.          Default_Palette.colora[(i*3)+2]);
  556.     }
  557. }
  558.  
  559. /******************************* COLOR **********************************/
  560. /*    Sets new foreground (drawing) and fill colours.            */
  561. /************************************************************************/
  562.  
  563. void color( char new_fill_colour, char new_draw_colour )
  564. {
  565.  
  566. new_draw_colour &= 0xff;    /* Mask colours to possible range.    */
  567. new_fill_colour &= 0xff;
  568. current_colour = new_draw_colour;
  569. fill_colour = new_fill_colour;
  570. update_pattern();        /* Update current pattern to reflect    */
  571.                 /*   the new colours.            */
  572. }
  573.  
  574. /******************************* FILLSTYLE ******************************/
  575. /*    Set the current fillstyle.                    */
  576. /************************************************************************/
  577.  
  578. static int current_pattern_no = 0, user_pattern[8];
  579.                 /* Current pattern and user pattern.    */
  580.  
  581. void fillstyle( unsigned char pattern, unsigned int pptr_offset,
  582.     unsigned int pptr_segment)
  583. {
  584. unsigned char far *pptr;
  585. int i;
  586.  
  587. pptr = MK_FP( pptr_segment, pptr_offset);    /* Ptr. to user line    */
  588.                         /*   style.        */
  589. current_pattern_no = pattern;        /* Save current style.        */
  590. if( current_pattern_no == 0xff )    /* User defined line style    */
  591.     {
  592.     set_pattern( (unsigned char *)¤t_pattern, pptr);
  593.                     /* Make pattern accessible to filling     */
  594.                 /*   routine.                */
  595.     for( i = 0; i < 8; i++)    /* Save User pattern for later use.    */
  596.          {
  597.      user_pattern[i] = *(int far *)(pptr + i*sizeof( int));
  598.      }
  599.     }
  600. else
  601.     {
  602.     set_pattern( (unsigned char *)current_pattern, 
  603.                  (unsigned char far *)&def_patterns[pattern]);
  604.                     /* Make pattern accessible to filling     */
  605.                 /*   routine.                */
  606.     }
  607. }
  608.  
  609. void update_pattern( void)    /* Update pattern to take care of new    */
  610. {                /*   colours.                */
  611.  
  612. if( current_pattern_no == 0xff )    /* User defined line style    */
  613.     {
  614.     set_pattern( (unsigned char *)current_pattern, 
  615.                  (unsigned char far *)user_pattern);
  616.                     /* Make pattern accessible to filling     */
  617.                 /*   routine.                */
  618.     }
  619. else
  620.     {
  621.     set_pattern( (unsigned char *)current_pattern, 
  622.                  (unsigned char far *)&def_patterns[current_pattern_no]);
  623.                     /* Make pattern accessible to filling     */
  624.                 /*   routine.                */
  625.     }
  626. }
  627.  
  628. /******************************* LINESTYLE ******************************/
  629. /*    Set the current line style.  This includes drawing pattern and    */
  630. /*  width.                                */
  631. /************************************************************************/
  632.  
  633. void linestyle( char style, int pattern, int width)
  634. {
  635.  
  636. switch( style)            /* Set appropriate line pattern.    */
  637.     {
  638.     case SOLID_LINE:
  639.          current_line_style = 0xffff;
  640.      break;
  641.  
  642.     case DOTTED_LINE:
  643.          current_line_style = 0xCCCC;
  644.      break;
  645.  
  646.     case CENTRE_LINE:
  647.          current_line_style = 0xFC78;
  648.      break;
  649.  
  650.     case DASHED_LINE:
  651.          current_line_style = 0xF8F8;
  652.      break;
  653.  
  654.     case USER_LINE:
  655.          current_line_style = pattern;
  656.      break;
  657.  
  658.     default:
  659.          break;
  660.     }
  661. current_line_width = width;        /* Save the width.        */
  662. }
  663.  
  664. /******************************* TEXTSTYLE ******************************/
  665. /*    Set the text path and size.  Returns x & y size as a long.    */
  666. /************************************************************************/
  667.  
  668. long textstyle( char number, char path, int xsize, int ysize)
  669. {
  670.  
  671. char_path = path;            /* Record path.            */
  672. char_size = xsize >> 3;            /* Convert text size to a    */
  673.                     /*  multiple of 8.        */
  674. if( char_size == 0)            /* Must be at least 1.        */
  675.     char_size = 1;
  676. xsize = ysize = char_size << 3;        /* Compute actual size.        */
  677. return( (((long)xsize) << 16) | ysize);    /* Return actual size.        */
  678. }
  679.  
  680. /******************************** TEXT **********************************/
  681. /*    Draw a text string.                        */
  682. /************************************************************************/
  683.  
  684. void text( int length, unsigned int offset, unsigned int segment)
  685. {
  686. char far * cptr = MK_FP( segment, offset);
  687. int i;
  688.  
  689. for( i = 0; i < length; ++i )         /* For all characters ...    */
  690.     {
  691.     char_draw( *cptr++);        /* Draw it.            */
  692.     }
  693. }
  694.  
  695. /****************************** FLOODFILL *******************************/
  696. /*    Unimplemented. Null function.  Is this really of importance to    */
  697. /*  anyone?                                */
  698. /************************************************************************/
  699.  
  700. void floodfill( int x, int y, unsigned char boundary)
  701. {
  702. }
  703.  
  704. /******************************* BITMAPUTIL *****************************/
  705. /*    Get the address of the bit map utility table.            */
  706. /************************************************************************/
  707.  
  708. void *bitmaputil( void )
  709. {
  710.  
  711. return(&Utility_Table);
  712. }
  713.  
  714. /*                                    */
  715. /*    The following define the bit map utility functions.        */
  716. /*                                    */
  717.  
  718. void enter_graphics( void )        /* Enter graphics mode function.*/
  719. {
  720. graphics_mode = 1;
  721. }
  722.  
  723. void leave_graphics( void )        /* Leave graphics mode function */
  724. {
  725. graphics_mode = 0;
  726. ROW_UPDATE();
  727. }
  728.  
  729. int bits_per_pixel( void )        /* Enter graphics mode function */
  730. {
  731.  
  732. return( 8);                /* Always 8 bits/pixel.        */
  733. }
  734.  
  735. void putpix( int x, int y, char colour)    /* Write a pixel function    */
  736. {
  737.  
  738. colour &= 0xff;
  739. CALC_ADDR( x, y);            /* Calculate address.        */
  740. POINT( colour);                /* Draw pixel.            */
  741. }
  742.  
  743. char getpix( int x, int y)        /* Read a pixel function    */
  744. {
  745.  
  746. CALC_ADDR( x, y);            /* Calculate address.        */
  747. return( RD_POINT());            /* Read pixel colour.        */
  748. }
  749.  
  750. void set_page( char page)        /* Set the active drawing page    */
  751. {
  752.  
  753. page_offset = 512L*512L*page;        /* Page starts here.        */
  754. }
  755.  
  756. void set_visual( char page)        /* Set the active display page    */
  757. {
  758.  
  759. DISPLAY_PAGE( page);
  760. }
  761.  
  762. void set_write_mode( int mode)        /* Set the current write mode    */
  763. {
  764.  
  765. current_write_mode = mode;        /* Save write mode.        */
  766. }
  767.  
  768.  
  769. /****************************** RESTOREBITMAP ***************************/
  770. /*    Copy a bitmap to video memory.                    */
  771. /************************************************************************/
  772.  
  773. void restorebitmap( char mode, unsigned int segment, unsigned int offset,
  774.         int x1, int y1, int x2, int y2)
  775. {
  776. const unsigned char far *buffer;
  777. int xsize, x3, y3, bump;
  778.  
  779. x1 = x2;        /* Bug in doc's. */
  780. y1 = y2;
  781.  
  782. buffer = (const unsigned char far *)MK_FP( segment, offset);
  783.                     /* Bitmap address.        */
  784. xsize = *(int far *)buffer + 1;        /* Columns.            */
  785. buffer += sizeof( int);
  786. y2 = y1 + *(int far *)buffer + 1;    /* Rows.            */
  787. bump = xsize;                /* Size of row in memory.  This    */
  788.                     /* should be agreed on with     */
  789.                     /* 'savebitmap'.        */
  790. buffer += sizeof(int);            /* Increment to storage.    */
  791. for( ;y1 < y2; y1++)            /* For each line...        */
  792.     {
  793.     x3 = x1;
  794.     y3 = y1;
  795.     CALC_ADDR( x3, y3);            /* Find the beginning.        */
  796.     copy_image( buffer, xsize, &line_buffer[current_column], xsize, mode);
  797.                         /* Copy the line using the    */
  798.                     /*  appropriate mode.        */
  799.     ROW_UPDATE();
  800.     buffer += bump;            /* Increment bitmap to the next    */
  801.     }                    /*  line.            */
  802. }
  803.  
  804. /****************************** SAVEBITMAP ******************************/
  805. /*    Copy an area of video memory to a bitmap.            */
  806. /************************************************************************/
  807.  
  808. void savebitmap( unsigned int buff_segment, unsigned int buff_offset,
  809.         int x1, int y1, int x2, int y2)
  810. {
  811. unsigned char far *buffer;
  812. int xsize, x3, y3, bump;
  813.  
  814. x1 = x2;        /* Bug in doc's. */
  815. y1 = y2;
  816. buffer = (unsigned char far *)MK_FP( buff_segment, buff_offset);
  817.                     /* Bitmap address.        */
  818. xsize = *(int far *)buffer + 1;        /* Columns.            */
  819. buffer += sizeof( int);
  820. y2 = y1 + *(int far *)buffer + 1;    /* Rows.            */
  821. bump = xsize;                /* Size of row in memory.  This    */
  822.                     /* should be agreed on with     */
  823.                     /* 'restorebitmap'.        */
  824. buffer += sizeof(int);            /* Increment to storage.    */
  825. for( ;y1 < y2; y1++)            /* For each line...        */
  826.     {
  827.     x3 = x1;
  828.     y3 = y1;
  829.     CALC_ADDR( x3, y3);            /* Find the beginning.        */
  830.     copy_image( &line_buffer[current_column], xsize, buffer, xsize, COPY);
  831.                         /* Copy the line using the    */
  832.                     /*  copy mode.            */
  833.     buffer += bump;            /* Increment bitmap to the next    */
  834.     }                    /*  line.            */
  835. }
  836.  
  837. /****************************** SETCLIP *********************************/
  838. /*    Set the clipping area.    Library?                */
  839. /************************************************************************/
  840.  
  841. void setclip( int x1, int y1, int x2, int y2)
  842. {
  843.  
  844. MINX = x1;                /* Save the clipping limits.    */
  845. MAXY = y1;
  846. MAXX = x2;
  847. MAXY = y2;
  848. }
  849.  
  850. /***************************** GET_PIXEL ********************************/
  851. /*    Read a pixel colour from the screen.                */
  852. /************************************************************************/
  853.  
  854. char get_pixel( int x, int y)
  855. {
  856.  
  857. CALC_ADDR( x, y);            /* Calculate the address.    */
  858. return( RD_POINT());            /* Read the pixel.        */
  859. }
  860.  
  861. /***************************** SET_PIXEL ********************************/
  862. /*    Set a pixel to a specific colour.                */
  863. /************************************************************************/
  864.  
  865. void set_pixel( int x, int y, char colour)
  866. {
  867.  
  868. colour &= 0xff;
  869. CALC_ADDR( x, y);            /* Calculate address.        */
  870. POINT( colour);                /* Draw the pixel.        */
  871. }
  872.  
  873. /****************************** TEXTSIZ *********************************/
  874. /*    Return the pixel size of a string.                */
  875. /************************************************************************/
  876.  
  877. long textsiz( int length, unsigned int offset, unsigned int segment)
  878. {
  879. if( char_path == NORMAL_PATH)        /* Horizontal.            */
  880.     {
  881.     return( (((long)(length*char_size*8))<<16) | (8*char_size));
  882.     }
  883. else                    /* Vertical.            */
  884.     {
  885.     return( (((long)(char_size*8))<<16) | (length*8*char_size));
  886.     }
  887. }
  888.  
  889. /****************************** COLOR_QUERY *****************************/
  890. /*    Get colour palette & size.                    */
  891. /************************************************************************/
  892.  
  893. long color_query( char command_type)
  894. {
  895. long ret_val;
  896.  
  897.  
  898. switch( command_type )            /* Act on the input command.    */
  899.     {
  900.     case 0:                /* Color palette size query.    */
  901.          ret_val = ((long)(255)) << 16;
  902.          ret_val |= 256;
  903.          break;
  904.  
  905.     case 1:                /* Default palette settings.    */
  906.          ret_val = (unsigned long)&Default_Palette;
  907.          break;
  908.  
  909.     default:                /* Unknown command.        */
  910.          break;
  911.     }
  912. return( ret_val);
  913. }
  914.  
  915. /********************* CHAR_DRAW ****************************************/
  916. /*    Draw a character.                        */
  917. /************************************************************************/
  918. void char_draw( unsigned char c)
  919. {
  920. static unsigned char char_bit_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
  921. const CHAR_TABLE_ENTRY far *current;
  922. int i, j, k, l, tx, ty;
  923. unsigned char row_cur;
  924.  
  925. if( c > 127) return;        /* Don't do upper 128.            */
  926. current = char_def + c;        /* Get character definition from ROM.    */
  927. if( char_path == NORMAL_PATH)    /* Draw horizontal.            */
  928.     {
  929.     for( i = 0; i < 8; i++)            /*  For each row...    */
  930.          {
  931.          row_cur = (current->row)[i];        /* Def. for this line.    */
  932.          for( j = 0; j < char_size; j++)    /* Size multiplier.    */
  933.               {
  934.           for( k = 0; k < 8; k++)         /*  For each column...    */
  935.                {
  936.                if( row_cur & char_bit_mask[k])    /* Column def.    */
  937.                     {
  938.                     for( l = 0; l < char_size; l++)    /* Draw 'size'    */
  939.                          {                /*  points.    */
  940.                  tx = CP_X;
  941.                  ty = CP_Y;
  942.                  DRAW_POINT( tx, ty);
  943.                      CP_X++;
  944.                      }
  945.                 }
  946.                else            /* Advance 'size' points.    */
  947.                     {
  948.                 CP_X += char_size;
  949.                     }
  950.                }
  951.           CP_X -= char_size*8;        /* Back to begining col.*/
  952.           CP_Y++;                /* Next line.        */
  953.           }
  954.          }
  955.     CP_X += char_size*8;        /* Next character.        */
  956.     CP_Y -= char_size*8;        /* Charcter top.        */
  957.     }
  958. else                /* Draw vertical.            */
  959.     {
  960.     for( i = 0; i < 8; i++)            /*  For each row...    */
  961.          {
  962.          row_cur = (current->row)[i];        /* Def. for this line.    */
  963.          for( j = 0; j < char_size; j++)    /* Size multiplier.    */
  964.               {
  965.           for( k = 0; k < 8; k++)         /*  For each column...    */
  966.                {
  967.                if( row_cur & char_bit_mask[k])    /* Column def.    */
  968.                     {
  969.                     for( l = 0; l < char_size; l++)
  970.                          {
  971.                  tx = CP_X;
  972.                  ty = CP_Y;
  973.                  DRAW_POINT( tx, ty);
  974.                      CP_Y--;
  975.                      }
  976.                 }
  977.                else            /* Advance 'size' points.    */
  978.                     {
  979.                 CP_Y -= char_size;
  980.                     }
  981.                }
  982.           CP_Y += char_size*8;        /* Back to begining col.*/
  983.           CP_X++;                  /* Next line.        */
  984.           }
  985.          }
  986.     CP_Y -= char_size*8;          /* Next character.        */
  987.     CP_X -= char_size*8;          /* Charcter top.        */
  988.     }
  989. }
  990.  
  991. /************************* COPY_IMAGE ***********************************/
  992. /*    Copy an image line from one area of memory to another.  The     */
  993. /*  source image is repeated as necessary to fill the destination.      */
  994. /*  This is sufficient to form the core of a basic set of two parameter    */
  995. /*  BiTBlT routines except for the fact that no precautions are taken     */
  996. /*  against overlap.  Could be sped up considerably by recoding in    */
  997. /*  assembly code.                            */
  998. /************************************************************************/
  999.  
  1000. void copy_image( 
  1001.     unsigned char const far *from, 
  1002.     int from_xsize, 
  1003.         unsigned char far *to, 
  1004.     int to_xsize,
  1005.     int mode
  1006.     )
  1007. {
  1008.  
  1009. switch( mode)                /* Copy mode.            */
  1010.     {
  1011.     case COPY:                /* Copy verbatim.        */
  1012.          copy_mem( from, from_xsize, to, to_xsize);
  1013.      break;
  1014.  
  1015.     case XOR:                       /* Copy xor.            */
  1016.          xor_mem( from, from_xsize, to, to_xsize);
  1017.      break;
  1018.  
  1019.     case OR:                       /* Copy or.            */
  1020.          or_mem( from, from_xsize, to, to_xsize);
  1021.      break;
  1022.  
  1023.     case AND:                       /* Copy and.            */
  1024.          and_mem( from, from_xsize, to, to_xsize);
  1025.      break;
  1026.  
  1027.     case NEGATE:                   /* Copy negate.            */
  1028.          neg_mem( from, from_xsize, to, to_xsize);
  1029.      break;
  1030.  
  1031.     default:
  1032.          break;
  1033.     }
  1034. }
  1035.  
  1036. /*************************** SET_PATTERN ********************************/
  1037. /*    Change a bit pattern into a colour image pattern that can be    */
  1038. /*  easily copied.  The bit pattern is an 8x8 pattern.            */
  1039. /************************************************************************/
  1040.  
  1041. void set_pattern( unsigned char *current_pattern, 
  1042.           unsigned char const far *pattern)
  1043. {
  1044. static unsigned char pat_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
  1045. int i, j;
  1046.  
  1047. for( i = 0; i < 8; i++)        /* For each line.            */
  1048.     {
  1049.     for( j = 0; j < 8; j++)    /* For each column.            */
  1050.          {
  1051.      if( (*pattern) & pat_mask[j])    /* Set to fill colour.        */
  1052.           {
  1053.           *current_pattern = fill_colour;
  1054.           }
  1055.      else            /* Or the background colour.        */
  1056.           {
  1057.           *current_pattern = background_colour;
  1058.           }
  1059.      current_pattern++;
  1060.      }
  1061.     pattern++;            /* Next line.                */
  1062.     }
  1063. }
  1064.  
  1065.  
  1066.